home *** CD-ROM | disk | FTP | other *** search
- Subject: v23i012: Netnews transmission daemon, Part02/03
- Newsgroups: comp.sources.unix
- Approved: rsalz@uunet.UU.NET
- X-Checksum-Snefru: b4e97780 d0334675 2eef814a 67669e60
-
- Submitted-by: Chris Myers <chris@wugate.wustl.edu>
- Posting-number: Volume 23, Issue 12
- Archive-name: newsxd/part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then feed it
- # into a shell via "sh file" or similar. To overwrite existing files,
- # type "sh file -c".
- # The tool that generated this appeared in the comp.sources.unix newsgroup;
- # send mail to comp-sources-unix@uunet.uu.net if you want that tool.
- # Contents: defs.h patchlevel.h process.c simple.conf util.c version.c
- # Wrapped by rsalz@litchi.bbn.com on Fri Jul 13 15:03:57 1990
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo If this archive is complete, you will see the following message:
- echo ' "shar: End of archive 2 (of 3)."'
- if test -f 'defs.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'defs.h'\"
- else
- echo shar: Extracting \"'defs.h'\" \(6742 characters\)
- sed "s/^X//" >'defs.h' <<'END_OF_FILE'
- X/* Define everything that all of the various pieces of code will be using */
- X
- X#include <stdio.h>
- X#include <signal.h>
- X#include <strings.h>
- X#include <syslog.h>
- X#include <nlist.h>
- X#include <errno.h>
- X#include <ctype.h>
- X#include <sys/param.h>
- X#include <sys/errno.h>
- X#include <sys/file.h>
- X#include <sys/ioctl.h>
- X#include <sys/wait.h>
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <varargs.h>
- X
- X#include "newsxd.h"
- X#include "patchlevel.h"
- X
- X/* If it's good enough for news 2.11, it's good enough for me ... */
- X
- X#ifdef BSD4_2
- X#include <sys/time.h>
- X#else
- X#include <time.h>
- X#endif
- X
- X#include <sys/resource.h>
- X
- X#if defined(mips) & defined(ultrix)
- X#include <sys/../h/fixpoint.h>
- X#endif
- X
- Xchar *calloc();
- X
- X#define foreach(ctl, list) for (ctl = list; ctl != NULL; ctl = ctl->next)
- X
- X#ifdef CNEWSLOCKING
- Xextern char *progname;
- X#endif
- X
- Xint debug, /* is debugging enabled */
- X DEBUG, /* painfully verbose debugging is enabled */
- X newsxdebug, /* run xmitter synchronously with debugging? */
- X tallying, /* is use of a tally file enabled? */
- X locking, /* is use of a locking file enabled? */
- X CONFIGCHANGED, /* a new configuration was read in */
- X#ifdef FAKESYSLOG
- X CONFIGCHANGEDFILE, /* a new configuration was read in */
- X#endif
- X queueinterval, /* number of seconds between xmit checks */
- X daemon_idle, /* prevent newsxd from running queue if set */
- X pidlist[MAXXMITTERS]; /* map pid --> xmitter quicker */
- X
- Xstruct host *pidmap[MAXXMITTERS];
- X
- Xchar batchfile[MAXPATHLEN], /* file inews places article IDs/paths in */
- X workfile[MAXPATHLEN], /* file to use for transmitter work file */
- X xmitlogs[MAXPATHLEN], /* where to log the output of transmitters */
- X tallyfile[MAXPATHLEN], /* where the tally file can be found */
- X statusfile[MAXPATHLEN], /* where newsxd's status should be written */
- X pidfile[MAXPATHLEN], /* where newsxd's pid should be written */
- X#ifdef FAKESYSLOG
- X fakelogfile[MAXPATHLEN],/* where is the newsxd log file? */
- X#endif
- X configfile[MAXPATHLEN]; /* where is the newsxd configuration file? */
- X
- X/* STRUCT OPTIONS
- X * Used to define the options controlling the starting of transmitters for
- X * classes and hosts.
- X *
- X * interval : minimum start-to-start interval for each host's transmitter
- X * startint : minimum interval between starting transmitters in this class
- X * ttl : maximum time-to-live (secs) for a transmitter in this class
- X * ttlpenalty : penalty time (secs) for a transmitter exceeding the ttl
- X * deltanice : amount to change nice before execing the transmitter
- X * maxload : maximum load where new xmitters can be started for this class
- X *
- X */
- X
- Xtypedef struct options {
- X
- X int deltanice;
- X int interval;
- X int startint;
- X int ttl;
- X int ttlpenalty;
- X int maxload;
- X
- X};
- X
- X/*
- X * STRUCT CLASS
- X * Contains the current state and description of each class of transmitters
- X * that newsxd handles.
- X *
- X * classname : textual name of this transmission class
- X * maxxmits : maximum number of simultaneous transmitters for this class
- X * curxmits : current number of active transmitters for this class
- X * laststart : last time a transmitter was started for this class
- X * xmitsernum : transmission serial number used for fair news transmission
- X * options : defines default transmitter startup parameters for this class
- X * members : number of hosts that are a member of this class
- X * flags : special option flags for this class
- X * 0 : don't rename <batchfile> to <workfile>
- X * 1 : don't look for <batchfile> or <workfile>
- X * xpath : file path for an alternate transmission program
- X * xargv : arguments to be passed to the alternate transmitter
- X * xargc : number of arguments to be passed to the alternate xmitter
- X * valid : used to detect which classes are valid after a config update
- X * next : pointer to the next class descriptor in the list
- X *
- X */
- X
- Xstruct class {
- X
- X char classname[MAXCLASSNAMELEN];
- X int maxxmits;
- X int curxmits;
- X int laststart;
- X int xmitsernum;
- X int members;
- X struct options options;
- X char slots[MAXCLASSXMITTERS];
- X int flags[MAXCLASSFLAGS];
- X char batchfile[MAXPATHLEN];
- X char workfile[MAXPATHLEN];
- X char xpath[MAXPATHLEN];
- X char *xargv[MAXEXECARGS];
- X int xargc;
- X char *debugargv[MAXEXECARGS];
- X int debugargc;
- X int valid;
- X struct class *next;
- X
- X};
- X
- X/*
- X * STRUCT HOST
- X * Contains the current state and description of each host that newsxd
- X * will be communicating with.
- X *
- X * hostname : name of the host to pass to the transmitter
- X * class : name of the transmission class this host is in
- X * times : list of valid times to transmit in UUCP L.sys format
- X * pid : pid of forked transmitter
- X * lasttime : last time transmitter was forked off
- X * xmitsernum : transmission serial number used for fair news transmission
- X * penaltytime : host xmitted to past ttl; secs before penalty is over
- X * whynot : why is there no transmitter running for this host NOW?
- X * valid : used to detect which hosts are valid after a config update
- X * options : defines default transmitter startup parameters for this host
- X * next : pointer to next host in the list of all hosts
- X * xargv : arguments to be passed to the transmitter
- X * xargc : number of arguments to be passed to the transmitter
- X *
- X */
- X
- Xstruct host {
- X
- X char hostname[MAXHOSTNAMELEN];
- X char class[MAXCLASSNAMELEN];
- X char times[MAXTIMENAMELEN];
- X int pid;
- X int lasttime;
- X int penaltytime;
- X int xmitsernum;
- X int whynot;
- X int valid;
- X int classslot;
- X struct options options;
- X char *xargv[MAXEXECARGS];
- X int xargc;
- X struct host *next;
- X
- X};
- X
- Xstruct class *classlist;
- Xstruct host *hostlist;
- X
- X/* Predefine the return types of all of the functions */
- X
- Xvoid addclass();
- Xvoid addhost();
- Xvoid clear_invalid();
- Xvoid daemon_start();
- Xvoid debug_off();
- Xvoid debug_on();
- Xvoid dprintf();
- Xvoid Dprintf();
- Xvoid dump_config();
- Xvoid dump_info();
- Xvoid idle();
- Xvoid reset();
- Xstruct class *getclass();
- Xvoid freeclassslot();
- Xint getclassslot();
- Xint getla();
- Xvoid kill_children();
- Xvoid log();
- Xvoid logerr();
- Xvoid make_invalid();
- Xint parsetime();
- Xvoid processarg();
- Xvoid read_config();
- Xvoid run_queue();
- Xint validtime();
- Xvoid xmit_done();
- END_OF_FILE
- if test 6742 -ne `wc -c <'defs.h'`; then
- echo shar: \"'defs.h'\" unpacked with wrong size!
- fi
- # end of 'defs.h'
- fi
- if test -f 'patchlevel.h' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'patchlevel.h'\"
- else
- echo shar: Extracting \"'patchlevel.h'\" \(41 characters\)
- sed "s/^X//" >'patchlevel.h' <<'END_OF_FILE'
- X#define VERSION 2.5
- X#define PATCHLEVEL 1
- END_OF_FILE
- if test 41 -ne `wc -c <'patchlevel.h'`; then
- echo shar: \"'patchlevel.h'\" unpacked with wrong size!
- fi
- # end of 'patchlevel.h'
- fi
- if test -f 'process.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'process.c'\"
- else
- echo shar: Extracting \"'process.c'\" \(20001 characters\)
- sed "s/^X//" >'process.c' <<'END_OF_FILE'
- X/*
- X * #include <legal/bs.h>
- X >
- X > Copyright (c) 1989 Washington University in Saint Louis, Missouri and
- X > Chris Myers. All rights reserved.
- X >
- X > Permission is hereby granted to copy, reproduce, redistribute or
- X > otherwise use this software as long as: (1) there is no monetary
- X > profit gained specifically from the use or reproduction of this
- X > software, (2) it is not sold, rented, traded, or otherwise marketed,
- X > (3) the above copyright notice and this paragraph is included
- X > prominently in any copy made, and (4) that the name of the University
- X > is not used to endorse or promote products derived from this software
- X > without the specific prior written permission of the University.
- X > THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X > IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X > WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X >
- X */
- X
- X#include "defs.h"
- Xextern int errno;
- X
- X/*************************************************************************/
- X/* FUNCTION : kill_children */
- X/* PURPOSE : Kills all outstanding transmitters. Kill_children will */
- X/* wait thirty seconds to allow all of the transmitters to */
- X/* exit gracefully. If invoked by a signal (SIGTERM?), exit */
- X/* else return to caller. */
- X/* ARGUMENTS : Signal number or 0 if to return to caller */
- X/*************************************************************************/
- X
- Xvoid
- Xkill_children(sig)
- X int sig; /* sig will be nonzero if called by SIGTERM */
- X
- X{
- Xstruct host *hostptr;
- X
- X if ((hostlist == NULL) && (sig == 0)) return;
- X
- X log(LOG_INFO, "newsxd: shutting down all transmitters\n");
- X
- X foreach (hostptr, hostlist) {
- X if (hostptr->pid != 0) {
- X dprintf("newsxd: killing transmitter for %s\n", hostptr->hostname);
- X (void) kill (hostptr->pid, SIGTERM);
- X }
- X }
- X
- X if (sig == 0) return;
- X
- X dprintf("(kill_children): sleeping 30 seconds\n");
- X
- X (void) sleep(30); /* allow transmitters to quit gracefully */
- X
- X log(LOG_INFO, "shut down by signal %d\n", sig);
- X
- X if (debug == 0 && DEBUG == 0) {
- X (void) unlink(pidfile);
- X (void) unlink(statusfile);
- X }
- X
- X (void) exit(0); /* invoked by SIGTERM, time to quit */
- X
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : xmit_done */
- X/* PURPOSE : Catch the SIGCHLD from completed transmitters and do the */
- X/* necessary cleanup. Also wait synchronously for a xmitter */
- X/* to complete; also perform forced cleanup for an xmitter */
- X/* ARGUMENTS : sig, > 0 if xmit_done is called by SIGCHLD */
- X/* == 0 if called to check for a zombie w/NOHANG */
- X/* ==-1 if called to sync wait for a transmitter */
- X/* < -1 to perform a forced cleanup on a transmitter */
- X/*************************************************************************/
- X
- Xvoid
- Xxmit_done(sig)
- X int sig; /* sig will be nonzero if called by SIGCHLD */
- X
- X{
- Xstruct host *hostptr;
- Xstruct class *classptr;
- Xunion wait status;
- Xstruct rusage usage;
- Xextern char *sys_errlist[];
- X
- Xint options,
- X loop,
- X pid;
- X
- X (void) sigsetmask(0);
- X
- X /*
- X * Try and catch any completed transmitters first and process them.
- X * Then, if xmit_done() was called to synchronously wait on a transmitter
- X * or to perform forced cleanup on a transmitter, do it.
- X */
- X
- X Dprintf("(xmit_done) sig %d\n", sig);
- X
- X while (1) {
- X if (sig != -1) options = WNOHANG;
- X
- X pid = wait3(&status, options, &usage);
- X
- X if (pid <= 0)
- X if (sig < -1) {
- X pid = -sig;
- X sig = 0;
- X } else {
- X Dprintf("(xmit_done) no process! pid=%d, errno=%s\n", pid,
- X sys_errlist[errno]);
- X return;
- X }
- X
- X Dprintf("(xmit_done) pid %d\n", pid);
- X
- X for (loop = 0; loop < MAXXMITTERS; loop++) {
- X if (pidlist[loop] == pid) {
- X hostptr = pidmap[loop];
- X pidlist[loop] = 0;
- X pidmap[loop] = (struct host *) NULL;
- X hostptr->pid = 0;
- X hostptr->whynot = WN_NOTMYTURN;
- X foreach (classptr, classlist) {
- X if (strcmp(hostptr->class, classptr->classname) == 0) {
- X classptr->curxmits--;
- X freeclassslot(classptr, hostptr->classslot);
- X dprintf("%s: transmission completed\n", hostptr->hostname);
- X return;
- X }
- X }
- X
- X /*
- X * The (sig < -1) check is here just in case a transmitter exitted
- X * normally just as run_queue tries to force a cleanup on it. If
- X * this isn't here, newsxd will abort with a corrupted data err.
- X */
- X
- X if (sig < -1) return;
- X
- X /* Something is seriously wrong here -- quit somewhat gracefully */
- X
- X logerr("CORRUPTED HOST/CLASS STRUCTURE!\n");
- X kill_children(1);
- X }
- X }
- X }
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : run_queue */
- X/* PURPOSE : Go through the list of hosts to transmit to and start any */
- X/* transmitter that meets all of the necessary conditions */
- X/* ARGUMENTS : none */
- X/*************************************************************************/
- X
- Xvoid
- Xrun_queue()
- X
- X{
- Xstruct host *hostptr;
- Xstruct class *classptr, *lastclass;
- Xstruct stat statbuf;
- Xstruct tm *curtime;
- X
- Xint clock,
- X pid,
- X hadtheirchance,
- X which,
- X which2,
- X loop,
- X loop2,
- X hostargc,
- X classargc;
- X
- Xchar fnbuf[MAXPATHLEN],
- X fnbuf2[MAXPATHLEN],
- X **hostargv,
- X **classargv;
- X
- X CONFIGCHANGED = 0;
- X hadtheirchance = 0;
- X lastclass = (struct class *) NULL;
- X
- X foreach (hostptr, hostlist) {
- X
- X /*
- X * If the configuration has been changed (possibly via SIGHUP), we
- X * need to assume that all of the current pointers and such are
- X * invalid since the current host MAY have been deleted...
- X *
- X * There is still a race condition, but this check lessens the chance
- X * of problems considerably.
- X *
- X */
- X
- X if (CONFIGCHANGED) {
- X dprintf("Reconfigured during queue run -- aborting queue run\n");
- X CONFIGCHANGED = 0;
- X return;
- X }
- X
- X (void) time(&clock);
- X curtime = localtime(&clock);
- X
- X classptr = getclass(hostptr->class);
- X
- X if (classptr != lastclass) {
- X if (lastclass) {
- X dprintf("class %s: members %d, hadtheirchance %d\n",
- X lastclass->classname, lastclass->members, hadtheirchance);
- X if (lastclass->members == hadtheirchance) {
- X lastclass->xmitsernum++;
- X dprintf("class %s: add 1 to xmitsernum, now %d\n",
- X lastclass->classname, lastclass->xmitsernum);
- X }
- X }
- X hadtheirchance = 0;
- X lastclass = classptr;
- X }
- X
- X /*
- X * Check and see if we somehow missed the SIGCHLD for a transmitter and
- X * it's really gone and we don't know it. If so, force a cleanup.
- X */
- X
- X if ((hostptr->pid) && (kill(hostptr->pid, 0) == -1) && (errno == ESRCH)) {
- X xmit_done(-hostptr->pid);
- X hostptr->pid = 0; /* Just in case xmit_done() missed it! */
- X }
- X
- X /*
- X * Check to see if the host has had a transmitter running for more
- X * than the ttl of its transmission class. If so, kill it.
- X */
- X
- X which = (hostptr->options.ttl) ?
- X hostptr->options.ttl : classptr->options.ttl;
- X which2 = (hostptr->options.ttlpenalty) ?
- X hostptr->options.ttlpenalty : classptr->options.ttlpenalty;
- X
- X dprintf("%s: checking ttl (%d/%d)\n", hostptr->hostname, which, which2);
- X
- X if ((hostptr->pid > 0) && (clock > (hostptr->lasttime + which))) {
- X dprintf("%s: exceeded ttl, killing\n");
- X hostptr->penaltytime = clock + which2;
- X if (kill(hostptr->pid, SIGTERM) != 0) xmit_done(-hostptr->pid);
- X hostptr->whynot = WN_TTL;
- X continue; /* skip this host to give others a chance */
- X }
- X
- X /*
- X * If there is already a running transmitter for this host, skip it. We
- X * don't want more than one!
- X */
- X
- X dprintf("%s: checking for active daemon (%d)\n", hostptr->hostname,
- X hostptr->pid);
- X
- X if (hostptr->pid > 0) {
- X hostptr->whynot = WN_RUNNING;
- X hadtheirchance++;
- X continue;
- X }
- X
- X /*
- X * Check to see if this host has already had a chance to start
- X * a transmitter. If so, let someone else have a chance.
- X */
- X
- X dprintf("%s: xmitsernum is %d, class xmitsernum is %d\n",
- X hostptr->hostname, hostptr->xmitsernum, classptr->xmitsernum);
- X
- X/*
- X if ((hostptr->xmitsernum == classptr->xmitsernum) &&
- X (classptr->maxxmits < classptr->members)) {
- X */
- X
- X if (hostptr->xmitsernum == classptr->xmitsernum) {
- X hadtheirchance++;
- X/* hostptr->whynot = WN_NOTMYTURN; */
- X continue;
- X }
- X
- X /*
- X * Check the current time against the last time an xmit was started
- X * for this class to make sure we don't start too many daemons at
- X * one time.
- X */
- X
- X which = (hostptr->options.startint) ?
- X hostptr->options.startint : classptr->options.startint;
- X
- X dprintf("%s: checking class startup interval (clock is %d, start %d)\n",
- X hostptr->hostname, clock, (classptr->laststart + which));
- X
- X if (clock < (classptr->laststart + which)) {
- X hostptr->whynot = WN_CLASSSTARTINT;
- X continue;
- X }
- X
- X /*
- X * Check the current load and compare against the maximum allowed
- X * load for starting new transmitters for this hosts's class.
- X */
- X
- X which = (hostptr->options.maxload) ?
- X hostptr->options.maxload : classptr->options.maxload;
- X
- X dprintf("%s: checking maximum load (cur %d, max %d)\n",
- X hostptr->hostname, getla(), which);
- X
- X if (getla() > which) {
- X hostptr->whynot = WN_LOAD;
- X continue;
- X }
- X
- X /*
- X * Check the number of currently running transmitters for this host's
- X * transmission class. If we're already running at the limit, skip
- X * this host.
- X */
- X
- X dprintf("%s (%s): checking running xmit count (%d of %d)\n",
- X hostptr->hostname, classptr->classname, classptr->curxmits,
- X classptr->maxxmits);
- X
- X if (classptr->curxmits >= classptr->maxxmits) {
- X hostptr->whynot = WN_MAXXMITS;
- X continue;
- X }
- X
- X /*
- X * All tests after this point should be tests for some characteristic
- X * of the host that would cause it to avoid its turn to start its
- X * transmitter. Things like: the host startup interval hasn't passed
- X * yet, or it's a bad time to send to that host, or there's no work
- X * to send to that host.
- X *
- X * Tests before this point should be tests for some characteristic not
- X * related to the particular host that prevents it from being able to
- X * start its transmitter. Things like: load too high, too many xmits
- X * already running...
- X */
- X
- X /*
- X * This host had a chance to send news (and can possibly skip it).
- X */
- X
- X hostptr->xmitsernum = classptr->xmitsernum;
- X hadtheirchance++;
- X
- X /*
- X * Check to see if the host had a transmitter killed because it ran
- X * longer than its class' ttl. If so, see if its penalty time is
- X * still unexpired.
- X */
- X
- X dprintf("%s: checking ttl penalty\n", hostptr->hostname);
- X
- X if (hostptr->penaltytime > clock) {
- X hostptr->whynot = WN_PENALTYTIME;
- X continue;
- X }
- X
- X /*
- X * Check the current time against the last time an xmit was started
- X * for this class to make sure we don't start a transmitter for this
- X * host too often...
- X */
- X
- X which = (hostptr->options.interval) ?
- X hostptr->options.interval : classptr->options.interval;
- X
- X dprintf("%s: checking host startup interval (%d)\n", hostptr->hostname,
- X which);
- X
- X if (clock < (hostptr->lasttime + which)) {
- X hostptr->whynot = WN_HOSTSTARTINT;
- X continue;
- X }
- X
- X /*
- X * Check to see that the current time is within the permitted range
- X * of transmission times. If not, skip this host.
- X */
- X
- X dprintf("%s: checking valid transmission times (%s)\n",
- X hostptr->hostname, hostptr->times);
- X
- X if (!validtime(hostptr->times)) {
- X hostptr->whynot = WN_BADTIME;
- X continue;
- X }
- X
- X /*
- X * See if there is an outstanding work file for this host, if so we
- X * just need to run a transmitter, otherwise rename the batch file
- X * to the work file and run the transmitter.
- X */
- X
- X (void) sprintf(fnbuf, workfile, hostptr->hostname);
- X
- X dprintf("%s: checking for workfile (%s)\n",
- X hostptr->hostname, fnbuf);
- X
- X if ((loop = stat(fnbuf, &statbuf)) != 0) {
- X Dprintf("%s: stat(%s) returned %d (errno is %d)\n", hostptr->hostname,
- X fnbuf, loop, errno);
- X
- X (void) sprintf(fnbuf2, batchfile, hostptr->hostname);
- X
- X dprintf("%s: checking for batchfile (%s)\n",
- X hostptr->hostname, fnbuf2);
- X
- X if (!classptr->flags[C_NOBATCH]) {
- X if ((loop = stat(fnbuf2, &statbuf)) != 0) {
- X Dprintf("%s: stat(%s) returned %d (errno is %d)\n",
- X hostptr->hostname, fnbuf, loop, errno);
- X
- X hostptr->whynot = WN_NOWORK;
- X continue;
- X } else {
- X hostptr->whynot = WN_RENAMEFAILED;
- X if (!classptr->flags[C_NOWORK] && rename(fnbuf2, fnbuf) != 0) {
- X dprintf("%s: rename failed (%s to %s)\n",
- X hostptr->hostname, fnbuf2, fnbuf);
- X continue;
- X }
- X }
- X }
- X }
- X
- X /*
- X * Fork off a transmitter for this host
- X */
- X
- X hostptr->whynot = WN_RUNNING;
- X
- X if ((hostptr->classslot = getclassslot(classptr)) == -1) {
- X hostptr->whynot = WN_NOSLOT;
- X exit(1);
- X }
- X
- X if ((pid = fork()) == 0) {
- X /* Child. */
- X int fd;
- X
- X /* Untrap all of the signals for newsxd; this is now a transmitter */
- X
- X (void) signal(SIGCHLD, SIG_DFL);
- X (void) signal(SIGHUP, SIG_DFL);
- X (void) signal(SIGQUIT, SIG_DFL);
- X (void) signal(SIGTERM, SIG_DFL);
- X (void) signal(SIGUSR1, SIG_DFL);
- X (void) signal(SIGUSR2, SIG_DFL);
- X (void) signal(SIGIO, SIG_DFL);
- X (void) signal(SIGIOT, SIG_DFL);
- X (void) signal(SIGTRAP, SIG_DFL);
- X
- X fd = open(classptr->flags[C_NOWORK] ? fnbuf2 : fnbuf, O_RDONLY);
- X if (fd > 0) (void) flock(fd, LOCK_EX);
- X
- X#ifdef CNEWSLOCKING
- X if (!classptr->flags[C_NOWORK]) {
- X
- X /* If we can get a valid lock then we know that since the batch
- X * file has been renamed to WORKFILE, cnews will now be writing
- X * to a different file (BATCHFILE).
- X */
- X (void) newslock();
- X (void) newsunlock();
- X }
- X#endif CNEWSLOCKING
- X
- X Dprintf("(%s): classslot is %d\n", hostptr->hostname,
- X hostptr->classslot);
- X
- X dprintf("%s: spawning transmitter\n", hostptr->hostname);
- X
- X if (!newsxdebug) {
- X (void) sprintf(fnbuf2, xmitlogs, hostptr->hostname);
- X (void) freopen(fnbuf2, "a", stdout);
- X (void) freopen(fnbuf2, "a", stderr);
- X }
- X
- X (void) fprintf(stderr, "%s: begin at %02d:%02d:%02d\n",
- X hostptr->hostname, curtime->tm_hour, curtime->tm_min,
- X curtime->tm_sec);
- X (void) fflush(stderr);
- X
- X which = (hostptr->options.deltanice) ?
- X hostptr->options.deltanice : classptr->options.deltanice;
- X
- X if (which != 0) {
- X Dprintf("Changing transmitter nice by %d for %s\n",
- X which, hostptr->hostname);
- X
- X (void) nice(which);
- X }
- X
- X if (classptr->xargc == 0) {
- X classptr = getclass("DEFAULT");
- X if (classptr->xargc == 0) {
- X logerr("host %s: No DEFAULT xmitter defined -- aborting\n",
- X hostptr->hostname);
- X (void) _exit(1);
- X }
- X }
- X
- X Dprintf("classptr->xargc = %d\n", classptr->xargc);
- X
- X Dprintf("%s: EXECing %s with parameters:\n",
- X hostptr->hostname, classptr->xpath);
- X
- X for (loop = 0; loop <= classptr->xargc; loop++) {
- X if (classptr->xargv[loop] == NULL) {
- X Dprintf("arg[%d] = NULL\n", loop);
- X } else {
- X Dprintf("arg[%d] = %s\n", loop, classptr->xargv[loop]);
- X }
- X }
- X
- X classargc = classptr->xargc;
- X classargv = classptr->xargv;
- X
- X classargv[classargc] = NULL;
- X
- X for (loop = 0; loop < classargc; loop++) {
- X hostargv = NULL;
- X if (strcmp(classargv[loop], "%f") == NULL) {
- X hostargc = hostptr->xargc;
- X hostargv = hostptr->xargv;
- X }
- X
- X if (strcmp(classargv[loop], "%d") == NULL) {
- X struct class *myclassptr = getclass(hostptr->class);
- X hostargc = myclassptr->debugargc;
- X hostargv = myclassptr->debugargv;
- X Dprintf("debug argc = %d\n", hostargc);
- X }
- X
- X if (hostargv != NULL) {
- X if (hostargc == 0) {
- X classargc--;
- X for (loop2 = loop; loop2 < MAXEXECARGS-1; loop2++)
- X classargv[loop2] = classargv[loop2 + 1];
- X } else {
- X classargc += hostargc - 1;
- X for (loop2 = MAXEXECARGS - hostargc; loop2 > loop; loop2--)
- X classargv[loop2 + hostargc - 1] = classargv[loop2];
- X for (loop2 = loop; loop2 < loop + hostargc; loop2++)
- X classargv[loop2] = hostargv[loop2 - loop];
- X loop += hostargc - 1;
- X }
- X }
- X }
- X
- X Dprintf("(after host flag insertion) classargc = %d\n",
- X classargc);
- X
- X for (loop = 0; loop <= classargc; loop++) {
- X /* WARNING: we are mangling the xargv array here! */
- X processarg(loop, hostptr, classptr);
- X
- X if (classargv[loop] == NULL) {
- X Dprintf("arg[%d] = NULL\n", loop);
- X } else {
- X Dprintf("arg[%d] = %s\n", loop, classargv[loop]);
- X }
- X }
- X
- X (void) execvp(classptr->xpath, classargv);
- X
- X logerr("%s: can't exec %s\n", hostptr->hostname, classptr->xpath);
- X
- X (void) _exit(1); /* could not exec the news transmitter! */
- X } else {
- X /* Parent. */
- X if (pid == -1) {
- X logerr("host %s: Can't fork child.\n", hostptr->hostname);
- X continue;
- X }
- X for (loop = 0; loop < MAXXMITTERS; loop++) {
- X if (pidlist[loop] == 0) {
- X pidlist[loop] = pid;
- X pidmap[loop] = hostptr;
- X Dprintf("%s: entered into pidmap/list at %d\n",
- X hostptr->hostname, loop);
- X break;
- X }
- X }
- X hostptr->pid = pid;
- X hostptr->lasttime = clock;
- X classptr->laststart = clock;
- X classptr->curxmits++;
- X if (newsxdebug) xmit_done(-1); /* wait for xmitter to complete */
- X }
- X }
- X
- X if (classptr->members == hadtheirchance) {
- X dprintf("class %s: add 1 to sernum (members %d, hadchance %d)\n",
- X classptr->classname, classptr->members, hadtheirchance);
- X classptr->xmitsernum++;
- X }
- X}
- END_OF_FILE
- if test 20001 -ne `wc -c <'process.c'`; then
- echo shar: \"'process.c'\" unpacked with wrong size!
- fi
- # end of 'process.c'
- fi
- if test -f 'simple.conf' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'simple.conf'\"
- else
- echo shar: Extracting \"'simple.conf'\" \(1073 characters\)
- sed "s/^X//" >'simple.conf' <<'END_OF_FILE'
- X# Define a service class that just runs an nntpxmit to each host
- X# every hour. Don't run nntpxmit if the load goes over 8.
- X
- Xclass normal maxxmits=1 interval=3600 maxload=8
- X
- X# Define the default news transmitter
- Xxmit DEFAULT /usr/local/lib/news/nntpxmit nntpxmit %h:%w
- X
- X# Check the list of hosts every 10 minutes to see if we can send news to
- X# someone yet.
- Xqueueinterval 600
- X
- X# In all of the following options, %s is replaced by the host name of the
- X# system being sent to.
- X
- X# File news places articles paths/ids in
- Xbatchfile /usr/spool/batch/%s
- X
- X# File a news transmitter wants articles paths/ids in
- Xworkfile /usr/spool/batch/%s.work
- X
- X# Hosts to send news to. Each line is of the format:
- X# CLASS VALID START
- X# host HOSTNAME NAME TIMES
- X
- Xhost dorothy normal Any
- Xhost toto normal Any
- Xhost wizard normal Any
- Xhost witch normal Any
- Xhost tinman normal Any
- Xhost lion normal Any
- END_OF_FILE
- if test 1073 -ne `wc -c <'simple.conf'`; then
- echo shar: \"'simple.conf'\" unpacked with wrong size!
- fi
- # end of 'simple.conf'
- fi
- if test -f 'util.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'util.c'\"
- else
- echo shar: Extracting \"'util.c'\" \(10869 characters\)
- sed "s/^X//" >'util.c' <<'END_OF_FILE'
- X/*
- X * #include <legal/bs.h>
- X >
- X > Copyright (c) 1989 Washington University in Saint Louis, Missouri and
- X > Chris Myers. All rights reserved.
- X >
- X > Permission is hereby granted to copy, reproduce, redistribute or
- X > otherwise use this software as long as: (1) there is no monetary
- X > profit gained specifically from the use or reproduction of this
- X > software, (2) it is not sold, rented, traded, or otherwise marketed,
- X > (3) the above copyright notice and this paragraph is included
- X > prominently in any copy made, and (4) that the name of the University
- X > is not used to endorse or promote products derived from this software
- X > without the specific prior written permission of the University.
- X > THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X > IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X > WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X >
- X */
- X
- X#include "defs.h"
- X
- X/*************************************************************************/
- X/* FUNCTION : daemon_start */
- X/* PURPOSE : To disassociate newsxd from the calling process so it can */
- X/* run as a daemon. */
- X/* ARGUMENTS : none */
- X/*************************************************************************/
- X
- Xvoid
- Xdaemon_start()
- X
- X{
- Xregister int childpid, fd;
- Xextern int errno;
- X
- X /* Ignore the terminal stop signals */
- X (void) signal(SIGTTOU, SIG_IGN);
- X (void) signal(SIGTTIN, SIG_IGN);
- X (void) signal(SIGTSTP, SIG_IGN);
- X
- X /* Fork and let the parent process exit */
- X if ((childpid = fork()) < 0) {
- X logerr("newsxd: can't fork to enter daemon mode\n");
- X (void) exit(1);
- X } else if (childpid > 0) exit(0);
- X
- X /* Lose the process group */
- X if (setpgrp(0, getpid()) == -1) {
- X logerr("newsxd: can't change pgrp to enter daemon mode\n");
- X (void) exit(1);
- X }
- X
- X /* Lose the controlling terminal */
- X if ((fd = open("/dev/tty", O_RDWR)) >= 0) {
- X (void) ioctl(fd, TIOCNOTTY, (char *) NULL);
- X (void) close(fd);
- X }
- X
- X /* Close any open files */
- X for (fd = 0; fd < NOFILE; fd++) (void) close(fd);
- X errno = 0;
- X
- X /* Set a proper default umask */
- X (void) umask(022);
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : getla */
- X/* PURPOSE : Return the current system load */
- X/* ARGUMENTS : none */
- X/* NOTES : this code stolen from sendmail 5.61 which stole it from */
- X/* from something else... */
- X/*************************************************************************/
- X
- Xint
- Xgetla()
- X
- X{
- X#if defined(sun) | defined(mips)
- Xlong avenrun[3];
- X#else
- Xdouble avenrun[3];
- X#endif
- Xextern off_t lseek();
- Xstatic int kmem = -1;
- X
- Xstatic struct nlist Nl[] =
- X{
- X { "_avenrun" },
- X#define X_AVENRUN 0
- X { 0 },
- X};
- X
- X
- X if (kmem < 0) {
- X kmem = open("/dev/kmem", 0, 0);
- X if (kmem < 0) return (-1);
- X (void) ioctl(kmem, (int) FIOCLEX, (char *) 0);
- X (void) nlist("/vmunix", Nl);
- X if (Nl[0].n_type == 0) return (-1);
- X }
- X
- X if (lseek(kmem, (off_t) Nl[X_AVENRUN].n_value, 0) == -1 ||
- X read(kmem, (char *) avenrun, sizeof(avenrun)) < sizeof(avenrun))
- X {
- X /* thank you Ian */
- X return (-1);
- X }
- X#ifdef sun
- X return ((int) (avenrun[0] + FSCALE/2) >> FSHIFT);
- X#else
- X#ifdef mips
- X return (FIX_TO_INT(avenrun[0]));
- X#else
- X return ((int) (avenrun[0] + 0.5));
- X#endif
- X#endif
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : processarg */
- X/* PURPOSE : Do %value substitutions in xargv */
- X/* ARGUMENTS : which value of argv to modify, hostptr, classptr */
- X/*************************************************************************/
- X
- Xvoid
- Xprocessarg(which, hostptr, classptr)
- X int which;
- X struct host *hostptr;
- X struct class *classptr;
- X
- X{
- Xchar buf1[MAXPATHLEN],
- X buf2[MAXPATHLEN],
- X charbuf[2],
- X *newxargv,
- X *strptr;
- X
- X if (classptr->xargv[which] == NULL) return;
- X
- X charbuf[1] = '\0';
- X *buf1 = '\0';
- X
- X for (strptr = classptr->xargv[which]; *strptr != '\0'; strptr++) {
- X if (*strptr != '%') {
- X charbuf[0] = *strptr;
- X (void) strcat(buf1, charbuf);
- X } else {
- X strptr++;
- X switch (*strptr) {
- X case 'h': (void) strcat(buf1, hostptr->hostname);
- X break;
- X case 'f': (void) strcat(buf1, "%f");
- X /* We shouldn't have seen a %f at this point! */
- X break;
- X case 'd': (void) strcat(buf1, "%d");
- X /* We shouldn't have seen a %d at this point! */
- X break;
- X case 'b': (void) sprintf(buf2, batchfile, hostptr->hostname);
- X (void) strcat(buf1, buf2);
- X break;
- X case 'w': if (classptr->flags[C_NOWORK])
- X (void) sprintf(buf2, batchfile, hostptr->hostname);
- X else
- X (void) sprintf(buf2, workfile, hostptr->hostname);
- X (void) strcat(buf1, buf2);
- X break;
- X case 's': (void) sprintf(buf2, "%d", hostptr->classslot);
- X (void) strcat(buf1, buf2);
- X break;
- X case '%': (void) strcat(buf1, "%"); /* %% changes to % */
- X break;
- X default : strptr--;
- X }
- X }
- X }
- X
- X newxargv = (char *) malloc(strlen(buf1) + 1);
- X (void) strcpy(newxargv, buf1);
- X classptr->xargv[which] = newxargv;
- X
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : parse_time */
- X/* PURPOSE : Check a single valid-time-string against the current time */
- X/* and return whether or not a match occurs. */
- X/* ARGUMENTS : a pointer to the time-string */
- X/*************************************************************************/
- X
- Xint
- Xparsetime(whattime)
- Xchar *whattime;
- X
- X{
- Xstatic char *days[] = { "Su", "Mo", "Tu", "We", "Th", "Fr", "Sa", "Wk" };
- Xlong clock;
- Xstruct tm *curtime;
- Xint wday, start, stop, ltime, validday, loop, match;
- X
- X (void) time(&clock);
- X curtime = localtime(&clock);
- X wday = curtime->tm_wday;
- X validday = 0;
- X match = 1;
- X
- X while (match && isalpha(*whattime) && isupper(*whattime)) {
- X match = 0;
- X for (loop = 0; loop < 8; loop++) {
- X if (strncmp(days[loop], whattime, 2) == NULL) {
- X whattime += 2;
- X match = 1;
- X if ((wday == loop) | ((loop == 7) && wday && (wday < 6))) {
- X validday = 1;
- X }
- X }
- X }
- X }
- X
- X if (strncmp(whattime, "Any", 3) == NULL) {
- X validday = 1;
- X whattime += 3;
- X }
- X
- X if (!validday) return 0;
- X
- X if (sscanf(whattime, "%d-%d", &start, &stop) == 2) {
- X ltime = curtime->tm_min + 100 * curtime->tm_hour;
- X if ((start < stop) && ((ltime > start) & ltime < stop)) return 1;
- X if ((start > stop) && ((ltime > start) | ltime < stop)) return 1;
- X } else return 1;
- X
- X return 0;
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : validtime */
- X/* PURPOSE : Break apart a set of valid time-strings and pass them to */
- X/* parse_time, returning whether or not ANY matches occurred */
- X/* ARGUMENTS : a pointer to the time-string */
- X/*************************************************************************/
- X
- Xint
- Xvalidtime(ptr)
- Xchar *ptr;
- X
- X{
- Xchar *nextptr;
- Xint good;
- X
- X while (1) {
- X nextptr = STRCHR(ptr, '|');
- X if (STRCHR(ptr, '|') == NULL) return(parsetime(ptr));
- X *nextptr = '\0';
- X good = parsetime(ptr);
- X *nextptr++ = '|'; /* gotta restore the | or things get skipped! */
- X if (good) return(1);
- X ptr = nextptr;
- X }
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : getclassslot */
- X/* PURPOSE : */
- X/* ARGUMENTS : a pointer to the class structure */
- X/* RETURNS : the slot number */
- X/*************************************************************************/
- X
- Xint getclassslot(classptr)
- Xstruct class *classptr;
- X
- X{
- Xint loop;
- X
- X for (loop = 0; loop < MAXCLASSXMITTERS; loop++)
- X if (classptr->slots[loop] != 'X') {
- X classptr->slots[loop] = 'X';
- X return loop;
- X }
- X
- X logerr("(getclassslot) Too many xmitters for class %s", classptr->classname);
- X return -1;
- X
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : freeclassslot */
- X/* PURPOSE : */
- X/* ARGUMENTS : slot number to free and a pointer to the class structure */
- X/*************************************************************************/
- X
- Xvoid freeclassslot(classptr, slot)
- Xstruct class *classptr;
- Xint slot;
- X
- X{
- X
- X classptr->slots[slot] = '.';
- X
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : idle */
- X/* PURPOSE : Set newsxd to idle mode. Don't process xmitter queue... */
- X/* ARGUMENTS : none */
- X/*************************************************************************/
- X
- Xvoid
- Xidle()
- X
- X{
- X
- X daemon_idle = 1;
- X
- X}
- X
- X/*************************************************************************/
- X/* FUNCTION : reset */
- X/* PURPOSE : Kill all outstanding transmitters and idle newsxd. */
- X/* ARGUMENTS : none */
- X/*************************************************************************/
- X
- Xvoid
- Xreset()
- X
- X{
- X
- X kill_children(0);
- X daemon_idle = 1;
- X
- X}
- X
- X#ifdef CNEWSLOCKING
- X
- X/*************************************************************************/
- X/* FUNCTION : unprivileged */
- X/* PURPOSE : keep the cnews libraries happy. */
- X/* ARGUMENTS : none used. */
- X/*************************************************************************/
- X
- Xint
- Xunprivileged(reason)
- Xchar *reason;
- X{
- X
- X}
- X
- X#endif CNEWSLOCKING
- END_OF_FILE
- if test 10869 -ne `wc -c <'util.c'`; then
- echo shar: \"'util.c'\" unpacked with wrong size!
- fi
- # end of 'util.c'
- fi
- if test -f 'version.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'version.c'\"
- else
- echo shar: Extracting \"'version.c'\" \(10181 characters\)
- sed "s/^X//" >'version.c' <<'END_OF_FILE'
- X/*
- X * #include <legal/bs.h>
- X >
- X > Copyright (c) 1989 Washington University in Saint Louis, Missouri and
- X > Chris Myers. All rights reserved.
- X >
- X > Permission is hereby granted to copy, reproduce, redistribute or
- X > otherwise use this software as long as: (1) there is no monetary
- X > profit gained specifically from the use or reproduction of this
- X > software, (2) it is not sold, rented, traded, or otherwise marketed,
- X > (3) the above copyright notice and this paragraph is included
- X > prominently in any copy made, and (4) that the name of the University
- X > is not used to endorse or promote products derived from this software
- X > without the specific prior written permission of the University.
- X > THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- X > IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- X > WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- X >
- X * newsxd: a daemon for controlling the transmission of news
- X *
- X * Written by
- X * Chris Myers Internet: chris@wugate.wustl.edu
- X * Software Engineer UUCP: ...!uunet!wugate!chris
- X * Office of the Network Coordinator BITNET: chris@wunet.bitnet
- X * Washington University in Saint Louis
- X *
- X * HISTORY:
- X * Version 0.1: first written in perl. A grand experiment that just didn't
- X * work very reliably (no reflection on the quality of perl, it
- X * just wasn't meant to do this kind of thing).
- X *
- X * Version 1.0: first C version
- X *
- X * 1.1: added per-host locking
- X * 1.2: added maxload qualifier
- X * 1.2.1: added time to live qualifier
- X *
- X * SOURCE CODE INADVERTANTLY DESTROYED (SIGH)
- X * Oh well, it needed rewriting anyway. :-)
- X *
- X * Version 2.0: here we go again. No per-host locking right now :-(
- X * Removed all static limits on the number of transmission
- X * classes and hosts. Everything is now malloc'ed.
- X * 2.0.1: added penalty time to time-to-live qualifier to allow other
- X * hosts to get news transmitters started.
- X * 2.1: Added the capability to specify a different transmission
- X * program (and parameters) for each transmission class. This
- X * was the motive for the name change from nntpxd to newsxd.
- X * 2.1.1: fixed bug caused by defunct transmitters which finally
- X * overran the ttl (did not do proper cleanup).
- X * 2.1.2: added patches for Pyramid and BSD 4.3 support from Warren
- X * Lavallee and Jim Lowe.
- X * 2.1.3: fixed bugs in calculating the ttl penalty and start/stop
- X * time ranges
- X * 2.1.4: fixed bug in read_config where the loop went 1 past the end
- X * of the options for a transmission class. This could cause
- X * the last parameter on a longer preceeding class line to be
- X * carried over to the subsequent classes.
- X * 2.1.5: somehow the default value for nntplogs slipped away from the
- X * code. Put it back in where it belongs.
- X * 2.1.6: added inter-host startup interval for classes so that newsxd
- X * doesn't start up too many daemons at once
- X * 2.1.7: fix stupid bug created in earlier patch where I set argptr[x]
- X * to NULL (what it was supposed to be) and then blithly reset it
- X * to something else -- preventing EXECing the program specified
- X * in an XMIT option. ARGH.
- X * 2.1.8: ARGH! Left out the code to make sure a transmitter for each
- X * host wasn't started up more often than <interval> seconds.
- X * 2.2: Cut down on the size of the wishlist by adding a bunch of
- X * features (and hopefully no more bugs):
- X * - syslog logging
- X * - lots of range/value checking on inputs
- X * - sort host/class names when inserting into list
- X * - move all configuration parameters into newsxd.h
- X * - add more error messages
- X * - document code even more
- X * - allow reconfiguration without killing outstanding xmitters
- X * - add a 'nobatchfile' switch
- X * - allocation of alternate xmitter parameters is now dynamic
- X * - Per-host delta-nice values for transmitters
- X * - make code more readable
- X * - write a manpage
- X * 2.3: Add SIGUSR1, SIGUSR2 to {en,dis}able debugging while running
- X * Shift the order of syslog initialization and switch to daemon
- X * Fix a "go past end of the array sometimes" bug in getclass().
- X * add "reason" to status display to show why xmitter not running
- X * in xmit options, %f=flags,%w=workfile,%b=batchfile,%h=hostname
- X * make transmission of news to hosts 'fair'
- X * minimize a race in run_queue if SIGQUIT causes reconfiguration
- X * change start/stop times to use UUCP-style permissible times
- X * 2.3.1: fix bug in incr xmitsernum when only one service class in use
- X * enable fair transmission code even if maxxmits > class members
- X * change use of strpbrk to strchr and make strchr #define'd
- X * 2.4: add per-host flags
- X * added check for multiply-defined host/class in add{host,class}
- X * zero classptr->members in addclass to allow reconfiguration
- X * 2.4.1: classptr->members++ in addhost was in the wrong spot
- X * buffer declaration for FAKESYSLOG had trailing ; should be ,
- X * log a reinitialization message after getting SIGHUP
- X * add -v switch to show version and logging
- X * if debugging == ON in daemon mode, don't dump status to stderr
- X * was closing pidfile with close() rather than fclose()
- X * change comments in xmit_done() to show sig==0 is NOHANG
- X * validtime() was mangling the valid times string
- X * parsetime() sometimes said a good time was not valid
- X * addhost() now resorts host list on reconfiguration
- X * 2.4.2: modify xmit_done() to almost always use WNOHANG on wait calls
- X * add_host() was improperly decrementing classptr->members
- X * When debugging changes, log "On"/"Off" not the value (0/-1)
- X * get rid of remaining code for obsolete "nntpxmit" keyword
- X * finish updating comments, changing "nntpxmit" to "transmitter"
- X * 2.5: sigsetmask(0) to allow SIGCHLD in xmit_done(); don't lose kids
- X * modify "Why Not Running" messages slightly for readability
- X * xmit_done() now loops to catch all completed transmitters
- X * run_queue() now checks for MIA transmitters and cleans 'em up
- X * if no classes defined, dump_config() now returns immediately
- X * break the source apart into several files from one big'un
- X * class options are default, w/host options overriding
- X * [ttl, interval, nice, maxload]
- X * run_queue() was setting whynotrunning wrong for active xmits
- X * moved ttl penalty check into "host gave up chance" code to
- X * prevent a penalized host from blocking others
- X * added SIGIO to idle newsxd until SIGHUP is received
- X * added class slots
- X * added faster pid->host mapping data structure
- X * added SIGTRAP to dump internal data structures for debugging
- X * 2.5.1: apply "lint" fixes from Andrew Partan <asp@uunet.uu.net>
- X * close and reopen logfiles on SIGHUP <asp@uunet.uu.net>
- X * put Why Not reasons in static array, use everywhere
- X * process.c: in fork()ed child, call _exit() not exit()
- X * check for duplicate newsxd running
- X * add support for per-class transmitter debugging flags
- X * fix an open file leak in config.c:read_config()
- X * add SIGIOT to kill all transmitters and idle newsxd
- X * add setuid(geteuid()), setgid(getegid()) in main()
- X * fix some potential null-ptr dereferencing problems in config.c
- X * fix array-index overrun problem in config.c <asp@uunet.uu.net>
- X * remove pidfile and statusfile on shutdown unless debug|DEBUG
- X * flock() the work file before EXECing the transmitter
- X * support CNEWS-style locking to prevent races on the work file
- X * restore default signal action after fork() for transmitter
- X *
- X * SPECIAL THANKS TO:
- X *
- X * Alpha tester: John Coolidge <coolidge@brutus.cs.uiuc.edu>
- X *
- X * Beta testers: Warren Lavallee <warren@schizo.samsung.com>
- X * Don Thomson <thomson@macc.wisc.edu>
- X * Michael A. Cooper <mcooper@usc.edu>
- X * Jim Lowe <james@csd4.csd.uwm.edu>
- X * David C. Lawrence <tale@pawl.rpi.edu>
- X * John Coolidge <coolidge@brutus.cs.uiuc.edu>
- X * Lloyd W. Taylor <lloyd@aplcen.apl.jhu.edu>
- X * Dave Alden <alden@shape.mps.ohio-state.edu>
- X * Greg Hackney <root@texbell.sbc.com>
- X * Rick Adams <rick@uunet.uu.net>
- X * Andrew Partan <asp@uunet.uu.net>
- X *
- X * This software has been tested on the following systems:
- X *
- X * DECstation 3100, Ultrix 3.1
- X * DEC VAX 8810, Ultrix 3.1
- X * Sun 3/60, SunOS 4.0.1
- X * Sun 3/180, SunOS 4.0.3
- X * Pyramid DualPort OSx
- X * DEC MicroVAX-II, BSD 4.3 UNIX
- X * DEC MicroVAX-II, Mt Xinu MORE/BSD 4.3
- X *
- X * Wishlist:
- X *
- X * - add logging of transmitter resource usage
- X * - Exponential backoff for failed transmission attempts
- X * - Per-host locking, using shlock-style locks
- X * - ability to specify min. # of articles queued before xmission starts
- X * - add per-class workfile and batchfile definitions
- X * - add per-host maximum delay between transmitter startups
- X *
- X */
- END_OF_FILE
- if test 10181 -ne `wc -c <'version.c'`; then
- echo shar: \"'version.c'\" unpacked with wrong size!
- fi
- # end of 'version.c'
- fi
- echo shar: End of archive 2 \(of 3\).
- cp /dev/null ark2isdone
- MISSING=""
- for I in 1 2 3 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 3 archives.
- rm -f ark[1-9]isdone
- else
- echo You still must unpack the following archives:
- echo " " ${MISSING}
- fi
- exit 0
- exit 0 # Just in case...
-